package com.have.blog.picture.service.impl;

import com.have.blog.base.constant.BlogConstant;
import com.have.blog.base.enums.BlogOpenStatus;
import com.have.blog.base.enums.BlogStatus;
import com.have.blog.base.enums.FilePriority;
import com.have.blog.base.holder.RequestHolder;
import com.have.blog.model.constant.SQLConstant;
import com.have.blog.model.mapper.TFileMapper;
import com.have.blog.model.mapper.TFileSortMapper;
import com.have.blog.model.models.*;
import com.have.blog.picture.constant.MessageConstant;
import com.have.blog.picture.constant.SystemConstant;
import com.have.blog.picture.service.FileService;
import com.have.blog.picture.service.LocalFileService;
import com.have.blog.picture.service.MinioService;
import com.have.blog.picture.service.QiniuService;
import com.have.blog.picture.utils.FeignUtil;
import com.have.blog.utils.FileUtils;
import com.have.blog.utils.JsonUtils;
import com.have.blog.utils.MyStringUtils;
import com.have.blog.utils.ResultUtils;
import com.have.blog.xo.constant.SysConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.*;

@Service
@Slf4j
@SuppressWarnings("all")
public class FileServiceImpl implements FileService {
    @Autowired
    private TFileMapper fileMapper;
    @Autowired
    private TFileSortMapper fileSortMapper;
    @Autowired
    private LocalFileService localFileService;
    @Autowired
    private MinioService minioService;
    @Autowired
    private QiniuService qiniuService;
    @Autowired
    private FeignUtil feignUtil;

    @Override
    public String cropperPicture(ArrayList<MultipartFile> list) {
        HttpServletRequest request = RequestHolder.getRequest();
        // 获取系统配置文件
        TSystemConfig systemConfig = feignUtil.getSystemConfig();
        String qiNiuPictureBaseUrl = systemConfig.getQiNiuPictureBaseUrl();
        String minioPictureBaseUrl = systemConfig.getMinioPictureBaseUrl();
        String localPictureBsaeUrl = systemConfig.getLocalPictureBaseUrl();
        String result = batchUploadFile(request, list, systemConfig);
        List<Map<String, Object>> resultListMap = new ArrayList<>();
        Map<String, Object> picMap = (Map<String, Object>) JsonUtils.jsonToObject(result, Map.class);
        if (SysConstant.SUCCESS.equals(picMap.get(SysConstant.CODE))) {
            List<Map<String, Object>> picData = (List<Map<String, Object>>) picMap.get(SysConstant.DATA);
            if (!CollectionUtils.isEmpty(picData)) {
                for (Map<String, Object> item : picData) {
                    Map<String, Object> tempMap = new HashMap<>();
                    tempMap.put(SysConstant.UID, item.get(SysConstant.UID));
                    if (FilePriority.QI_NIU.equals(systemConfig.getPicturePriority()) && !StringUtils.isEmpty(qiNiuPictureBaseUrl)) {
                        tempMap.put(SysConstant.URL, qiNiuPictureBaseUrl + item.get(SysConstant.QI_NIU_URL));
                    } else if (FilePriority.MINIO.equals(systemConfig.getPicturePriority()) && !StringUtils.isEmpty(minioPictureBaseUrl)) {
                        tempMap.put(SysConstant.URL, minioPictureBaseUrl + item.get(SysConstant.MINIO_URL));
                    } else {
                        tempMap.put(SysConstant.URL, localPictureBsaeUrl + item.get(SysConstant.PIC_URL));
                    }
                    resultListMap.add(tempMap);
                }
            }
        }
        return ResultUtils.successWithData(resultListMap);
    }

    @Override
    public String getPicture(String fileIds, String code) {
        if (StringUtils.isEmpty(code)) {
            code = BlogConstant.SYMBOL_COMMA;
        }
        if (StringUtils.isEmpty(fileIds)) {
            log.error(MessageConstant.PICTURE_UID_IS_NULL);
            return ResultUtils.errorWithMessage(MessageConstant.PICTURE_UID_IS_NULL);
        }
        List<Map<String, Object>> list = new ArrayList<>();
        List<String> fileIdList = MyStringUtils.changeStringToStringList(fileIds, code);
        TFileExample example = new TFileExample();
        example.createCriteria()
                .andUidIn(fileIdList);
        List<TFile> fileList = fileMapper.selectByExample(example);
        if (!CollectionUtils.isEmpty(fileIdList)) {
            for (TFile file : fileList) {
                if (file != null) {
                    HashMap<String, Object> map = new HashMap<>();
                    // TODO 获取七牛云地址
                    map.put(SystemConstant.QI_NIU_URL, file.getQiNiuUrl());
                    // TODO 获取MINIO对象储存地址
                    map.put(SystemConstant.MINIO_URL, file.getMinioUrl());
                    // 获取本地Niginx服务器地址
                    map.put(SystemConstant.URL, file.getPicUrl());
                    // 图片后缀名
                    map.put(SystemConstant.EXPANDED_NAME, file.getPicExpandedName());
                    map.put(SystemConstant.FILE_OLD_NAME, file.getFileOldName());
                    // 名称
                    map.put(SystemConstant.NAME, file.getPicName());
                    map.put(SystemConstant.UID, file.getUid());
                    map.put(SQLConstant.FILE_OLD_NAME, file.getFileOldName());
                    list.add(map);
                }
            }
        }
        return ResultUtils.successWithData(list);
    }

    // TODO  批量插入修改
    @Transactional
    @Override
    public String batchUploadFile(HttpServletRequest request, List<MultipartFile> filedatas, TSystemConfig systemConfig) {
        String uploadQiNiu = systemConfig.getUploadQiNiu();
        String uploadLocal = systemConfig.getUploadLocal();
        Integer uploadMinio = systemConfig.getUploadMinio();


        // 1. 判断来源
        String source = request.getParameter(SysConstant.SOURCE);
        // 如果是用户上传，则需要上传用户uid
        String userUid = "";
        // 如果是管理员上传，则需要上传管理员uid
        String adminUid = "";
        // 项目名
        String projectName = "";
        // 模块名
        String sortName = "";

        // 判断图片来源
        if (SysConstant.PICTURE.equals(source)) {
            // 当从vue-blog-web网站过的直接从参数中获取
            userUid = request.getParameter(SysConstant.USER_UID);
            adminUid = request.getParameter(SysConstant.ADMIN_UID);
            projectName = request.getParameter(SysConstant.PROJECT_NAME);
            sortName = request.getParameter(SysConstant.SORT_NAME);
        } else {
            // 当从vue-blog-admin传过来时
            userUid = request.getAttribute(SysConstant.USER_UID).toString();
            adminUid = request.getAttribute(SysConstant.ADMIN_UID).toString();
            projectName = request.getAttribute(SysConstant.PROJECT_NAME).toString();
            sortName = request.getAttribute(SysConstant.SORT_NAME).toString();
        }

        if (StringUtils.isEmpty(projectName)) {
            projectName = "base";
        }

        if (StringUtils.isEmpty(userUid) && StringUtils.isEmpty(adminUid)) {
            return ResultUtils.errorWithMessage("请先注册");
        }
        TFileSortExample example = new TFileSortExample();
        example.createCriteria()
                .andSortNameEqualTo(sortName)
                .andProjectNameEqualTo(projectName)
                .andStatusEqualTo(BlogStatus.ENABLE.getStatus());
        List<TFileSort> fileSortList = fileSortMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(fileSortList)) {
            return ResultUtils.errorWithMessage("文件不允许被上传");
        }

        // 如果url为空，使用默认url
        TFileSort fileSort =fileSortList.get(0);
        String sortUrl = fileSort.getUrl();
        if (StringUtils.isEmpty(sortUrl)) {
            sortName = "base/common/";
        }

        List<TFile> list = new ArrayList<>();
        // 文件上传
        if (!CollectionUtils.isEmpty(filedatas)) {
            for (MultipartFile filedata : filedatas) {
                String oldName = filedata.getOriginalFilename();
                long size = filedata.getSize();
                // 获取扩展名
                String picExpandedName = FileUtils.getPicExpandedName(oldName);
                // 获取新文件名
                String newFileName = System.currentTimeMillis() + BlogConstant.SYMBOL_POINT + picExpandedName;
                String loadlUrl = "";
                String qiNiuUrl = "";
                String minioUrl = "";
                try {
                    if (BlogOpenStatus.OPEN.equals(uploadQiNiu)) {
                        qiNiuUrl = qiniuService.uploadFile(filedata, newFileName);
                    }

                    if (BlogOpenStatus.OPEN.equals(uploadMinio)) {
                        minioUrl = minioService.uploadFile(filedata, newFileName);
                    }

                    if (BlogOpenStatus.OPEN.equals(uploadLocal)) {
                        loadlUrl = localFileService.uploadFile(filedata, fileSort, newFileName);
                    }
                } catch (Exception e) {
                    log.info("上传文件异常:{}", e.getMessage());
                    e.getStackTrace();
                    return ResultUtils.errorWithMessage("文件上传失败，请检查系统配置");
                }

                TFile file = new TFile();
                file.setUid(MyStringUtils.getUUID());
                file.setFileOldName(oldName);
                file.setFileSortUid(fileSort.getUid());
                file.setFileSize((int) size);
                file.setPicExpandedName(picExpandedName);
                file.setPicUrl(loadlUrl);
                file.setStatus(BlogStatus.ENABLE.getStatus());
                file.setUserUid(userUid);
                file.setAdminUid(adminUid);
                file.setPicName(newFileName);
                file.setQiNiuUrl(qiNiuUrl);
                file.setMinioUrl(minioUrl);
                file.setUpdateTime(new Date());
                file.setCreateTime(new Date());
                fileMapper.insert(file);
                list.add(file);
            }
            return ResultUtils.successWithData(list);
        }
        return ResultUtils.errorWithMessage("请上传图片");
    }
}
